﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Marmat.Forms
{
    public abstract class ObjectCollection<T> : IList, IList<T>
    {
        private readonly List<T> collection;

        public ObjectCollection()
        {
            this.collection = new List<T>();
        }

        /// <summary>
        /// 获取或设置指定索引处的元素。
        /// </summary>
        /// <param name="index">要获取或设置的元素的从零开始的索引。</param>
        /// <returns></returns>
        public virtual T this[int index]
        {
            get => this.collection[index];
            set => this.collection[index] = value;
        }

        object IList.this[int index]
        {
            get => ((IList)this.collection)[index];
            set => ((IList)this.collection)[index] = value;
        }

        /// <summary>
        /// 获取 System.Collections.Generic.List`1 中包含的元素数。
        /// </summary>
        public virtual int Count => this.collection.Count;

        bool IList.IsReadOnly => ((IList)this.collection).IsReadOnly;
        bool ICollection<T>.IsReadOnly => ((ICollection<T>)this.collection).IsReadOnly;
        bool IList.IsFixedSize => ((IList)this.collection).IsFixedSize;
        object ICollection.SyncRoot => ((ICollection)this.collection).SyncRoot;
        bool ICollection.IsSynchronized => ((ICollection)this.collection).IsSynchronized;

        /// <summary>
        /// 将某项添加到 System.Collections.Generic.ICollection`1 中。
        /// </summary>
        /// <param name="item"></param>
        public virtual void Add(T item)
        {
            IList list = this;
            list.Add(item);
        }

        int IList.Add(object value)
        {
            if (value is T item)
                return ((IList)this.collection).Add(item);
            else
                throw new InvalidCastException();
        }

        /// <summary>
        /// 从 System.Collections.Generic.ICollection`1 中移除所有项。
        /// </summary>
        public virtual void Clear()
        {
            this.collection.Clear();
        }

        /// <summary>
        /// 确定某元素是否在 System.Collections.Generic.List`1 中。
        /// </summary>
        /// <param name="item">要在 System.Collections.Generic.List`1 中定位的对象。 对于引用类型，该值可以为 null。</param>
        /// <returns></returns>
        public virtual bool Contains(T item)
        {
            return this.collection.Contains(item);
        }

        bool IList.Contains(object value)
        {
            if (value is T item)
                return this.Contains(item);
            else
                throw new InvalidCastException();
        }

        /// <summary>
        /// 从目标数组的指定索引处开始，将整个 System.Collections.Generic.List`1 复制到兼容的一维数组。
        /// </summary>
        /// <param name="array">一维 System.Array，它是从 System.Collections.Generic.List`1 复制的元素的目标。 System.Array 必须具有从零开始的索引。</param>
        /// <param name="arrayIndex">array 中从零开始的索引，从此处开始复制。</param>
        public virtual void CopyTo(T[] array, int arrayIndex)
        {
            this.collection.CopyTo(array, arrayIndex);
        }

        void ICollection.CopyTo(Array array, int index)
        {
            if (array is T[] list)
                this.CopyTo(list, index);
            else
                throw new InvalidCastException();
        }

        /// <summary>
        /// 返回循环访问 System.Collections.Generic.List`1 的枚举数。
        /// </summary>
        /// <returns></returns>
        public IEnumerator<T> GetEnumerator()
        {
            return this.collection.GetEnumerator();
        }

        /// <summary>
        /// 搜索指定的对象，并返回整个 System.Collections.Generic.List`1 中第一个匹配项的从零开始的索引。
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        public virtual int IndexOf(T item)
        {
            return this.collection.IndexOf(item);
        }

        int IList.IndexOf(object value)
        {
            if (value is T item)
                return this.IndexOf(item);
            else
                throw new InvalidCastException();
        }

        /// <summary>
        /// 将元素插入 System.Collections.Generic.List`1 的指定索引处。
        /// </summary>
        /// <param name="index">应插入 item 的从零开始的索引。</param>
        /// <param name="item">要插入的对象。 对于引用类型，该值可以为 null。</param>
        public virtual void Insert(int index, T item)
        {
            this.collection.Insert(index, item);
        }

        void IList.Insert(int index, object value)
        {
            if (value is T item)
                this.Insert(index, item);
            else
                throw new InvalidCastException();
        }

        public virtual bool Remove(T item)
        {
            return this.collection.Remove(item);
        }

        void IList.Remove(object value)
        {
            if (value is T item)
                this.Remove(item);
            else
                throw new InvalidCastException();
        }

        /// <summary>
        /// 移除 System.Collections.Generic.List`1 的指定索引处的元素。
        /// </summary>
        /// <param name="index">要移除的元素的从零开始的索引。</param>
        public virtual void RemoveAt(int index)
        {
            this.collection.RemoveAt(index);
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return this.GetEnumerator();
        }
    }
}
